"""
Pipeline forward.
Extra state.
This one doesn't really work and I never finished it.
"""


def get_resources_free(instructions_state, pipeline_state, registers_state):
    assert instructions_state is not None
    assert pipeline_state is not None
    assert registers_state is not None
    return True


def get_pipeline_state(cycles, instructions):
    """
    This implementation does not use forwarding and all EX operations
    only take 1 cycle.

    1. take an instruction
    2. if the instruction is ready, add to the pipeline
    3. if the instruction is running and not blocked, advance to the next pipeline stage

    TODO: resource management, stalling

    """

    pipeline_state = {
        "IF": "",
        "ID": "",
        "EX": "",
        "MEM": "",
        "WB": "",
    }

    # TODO: x0-x31, f0-f31
    registers_state = {
        "x0": "",
        "x1": "",
        "x2": "",
    }

    cycle_state = []

    instructions_state = []
    for item in instructions[:cycles]:
        current = {"instruction": item, "state": ""}
        instructions_state.append(current)

    for cycle in range(1, cycles + 1):
        for index, instruction in enumerate(instructions_state):
            instruction_state = instruction.get("state")
            if instruction_state == "done":
                pass
            elif instruction_state == "" and pipeline_state["IF"] == "":
                instruction["state"] = "IF"
                pipeline_state["IF"] = index
            elif instruction_state == "IF" and pipeline_state["ID"] == "":
                resources_free = get_resources_free(
                    instructions_state, pipeline_state, registers_state
                )
                if not resources_free:
                    # NOTE: This should imply a stall
                    continue
                instruction["state"] = "ID"
                pipeline_state["ID"] = index
                pipeline_state["IF"] = ""
            elif instruction_state == "ID" and pipeline_state["EX"] == "":
                instruction["state"] = "EX"
                pipeline_state["EX"] = index
                pipeline_state["ID"] = ""
            elif instruction_state == "EX" and pipeline_state["MEM"] == "":
                instruction["state"] = "MEM"
                pipeline_state["MEM"] = index
                pipeline_state["EX"] = ""
            elif instruction_state == "MEM" and pipeline_state["WB"] == "":
                instruction["state"] = "WB"
                pipeline_state["WB"] = index
                pipeline_state["MEM"] = ""
            elif instruction_state == "WB":
                instruction["state"] = "done"
                pipeline_state["WB"] = ""

        # print(cycle)
        # print(pipeline_state)
        # print(instructions_state)

        filtered_state = {
            key: value for key, value in pipeline_state.items() if value != ""
        }
        if filtered_state:
            current_cycle = {
                "cycle": cycle,
                "state": filtered_state,
            }
            cycle_state.append(current_cycle)

    return cycle_state
